package zrpcservice

import (
	"znet/zrpc"
	"znet/zconf"
	"znet/glog"
	"time"
	"znet/zconst/zcmd"
	"znet/zconst"
)

type OnClientEvent interface {
	OnConnectionSuccess(cNode *RpcServiceNode)
	OnConnectionFail(cNode *RpcServiceNode)
}

type RpcServiceNode struct {
	*zrpc.RpcClient

	ConfServer 		zconf.Service
	ConfRpc 		zconf.RpcService
	NeedReg 		bool						// 是否需要注册
	IsReq 			bool 						// 是否已经注册
	OnClientEvent 	OnClientEvent				//

	RegChan 		chan bool					// 需要注册Channel
	OpenChan 		chan struct{}				// 连接成功的Channel
	CloseChan 		chan struct{}				// 断开连接的Channel
}
func (this *RpcServiceNode) InitClient(cConf zconf.RpcService,onClientEvent OnClientEvent){
	this.ConfRpc 		= cConf
	this.NeedReg 		= cConf.NeedReg
	this.OnClientEvent 	= onClientEvent
	this.RpcClient 		= &zrpc.RpcClient{
		Name:cConf.Name,
		Addr:cConf.Attr,
		RequestTimeout:cConf.RequestTimeout,
		OnClientEvent:this,
	}
	this.RpcClient.Init()
	this.RpcClient.AddService(cConf.Name,&zrpc.ServiceImpl{})
	this.RpcClient.Start()

	if this.NeedReg {
		this.CloseChan 	= make(chan struct{})
		this.OpenChan 	= make(chan struct{})
		this.RegChan 	= make(chan bool)
		this.regHandle()
	}
}
func (this *RpcServiceNode) OnConnectionSuccess(client *zrpc.RpcClient){
	if this.OnClientEvent != nil {
		this.OnClientEvent.OnConnectionSuccess(this)
	}
	if this.NeedReg {
		this.OpenChan <- struct{}{}
	}
}
func (this *RpcServiceNode) OnConnectionFail(client *zrpc.RpcClient){
	if this.OnClientEvent != nil {
		this.OnClientEvent.OnConnectionFail(this)
	}
	if this.NeedReg {
		this.CloseChan<- struct{}{}
	}
}
func (this *RpcServiceNode) regHandle(){
	go func() {
		for  {
			select {
			case this.IsReq=<-this.RegChan:
			case <-this.OpenChan:
			case <-this.CloseChan:
				go func() {
					this.RegChan<-false
				}()
			}
			if !this.IsReq && this.IsConnected(){
				// 未注册已连接
				go func() {
					this.RegChan<-this.RegClient()
				}()
				select {
				// 不成功5秒重复注册
				case <-time.After(time.Second*2):
				}
			}
		}
	}()
}
func (this *RpcServiceNode) RegClient()  (bool){
	args := zconf.RpcService{
		Name:this.ConfServer.Name,
		Attr:this.ConfServer.Attr,
	}
	glog.Infof("向[%s](%s) 注册 [%s]（%s）",this.ConfRpc.Name,this.ConfRpc.Attr,this.ConfServer.Name,this.ConfServer.Attr)
	r,err := this.Call(zconst.OnRpcMessage,zrpc.NewRpcArgsRes(zcmd.CMD_ZNET_REGITSER,args))
	if err != nil {
		glog.Errorf("向[%s](%s) 注册失败：%s",this.ConfRpc.Name,this.ConfRpc.Attr,err)
		glog.Error(err)
		return false
	}
	rpcRes := zrpc.ReturnRpcArgsRes(r)
	if rpcRes.Error != ""{
		glog.Errorf("向[%s](%s) 注册失败：%s",this.ConfRpc.Name,this.ConfRpc.Attr,rpcRes.Error)
		return false
	}
	res := rpcRes.Data2Bool()
	glog.Infof("向[%s](%s) 注册成功",this.ConfRpc.Name,this.ConfRpc.Attr)
	return res
}
